/*
** Transfer.c
** handle disk image to PC transfer.
*/

#include "dis6502.h"
#include "atari.h"

#define TITRE_TRANSFERT "File Transfer"

static char szAtariDiskFile[_MAX_PATH];
static char szTransferDirPC[_MAX_PATH];
static char szTransferFilePC[_MAX_PATH];
static char szTransferPath[_MAX_PATH];
static char szTransferFile[_MAX_PATH];
static BOOL bTransferDiskLoaded;
static BOOL bTransferAtariSelected;
static BOOL bTransferPCSelected;

void BuildPath(char *szResult, char *szPath, char *szFile)
{
     strcpy(szResult, szPath);
     if (szResult[strlen(szResult) - 1] != '\\')
          strcat(szResult, "\\");
     strcat(szResult, szFile);
}

static AtariError ShowAtariError(HWND hDlg, AtariError iRet)
{
     switch (iRet)
          {
          case ATARI_ERR_DISK_NOT_FOUND:
               MessageBox(hDlg, "Atari error:\nDisk file not found !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
               break;
          case ATARI_ERR_DIRECTORY_NOT_FOUND:
               MessageBox(hDlg, "Atari error:\nDirectory (VTOC) not found !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
               break;
          case ATARI_ERR_DIRECTORY_READ:
               MessageBox(hDlg, "Atari error:\nError reading directory (VTOC) sectors !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
               break;
          case ATARI_ERR_DIRECTORY_WRITE:
               MessageBox(hDlg, "Atari error:\nError writing directory (VTOC) sectors !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
               break;
          case ATARI_ERR_INVALID_VTOC_ENTRY:
               MessageBox(hDlg, "Atari error:\nInvalid directory (VTOC) entry !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
               break;
          case ATARI_ERR_SECTOR_NOT_FOUND:
               MessageBox(hDlg, "Atari error:\nSector not found !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
               break;
          case ATARI_ERR_FILE_READ:
               MessageBox(hDlg, "Atari error:\nFile can not be read !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
               break;
          case ATARI_ERR_FILE_WRITE:
               MessageBox(hDlg, "Atari error:\nFile can not be written !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
               break;
          case ATARI_ERR_FILE_CORRUPTED:
               MessageBox(hDlg, "Atari error:\nFile corrupted (sector links) !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
               break;
          case ATARI_ERR_FILE_LENGTH:
               MessageBox(hDlg, "Atari error:\nEnd-of-file does not match sector count !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
               break;
          case ATARI_ERR_FILE_ALREADY_EXISTS:
               MessageBox(hDlg, "Atari error:\nFile already exists on this disk !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
               break;
          case ATARI_ERR_NO_FREE_SECTOR:
               MessageBox(hDlg, "Atari error:\nNo free sector (disk full) !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
               break;
          case ATARI_ERR_BITMAP_READ:
               MessageBox(hDlg, "Atari error:\nError reading Volume Bitmap sector !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
               break;
          case ATARI_ERR_BITMAP_WRITE:
               MessageBox(hDlg, "Atari error:\nError writing Volume Bitmap sector !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
               break;
          case ATARI_ERR_SECTOR_ALREADY_FREE:
               MessageBox(hDlg, "Atari error:\nThe sector to be freed is already free !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
               break;
          case ATARI_ERR_FILE_SEEK:
               MessageBox(hDlg, "Atari error:\nError while seeking end of file !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
               break;
          }
     return iRet;
}

static BOOL ReadAtariDirectory(HWND hDlg, char *szFile, WORD wListID, WORD wTotalID)
{
AtariFile Info;
WORD wTotal;
WORD wLng;
DWORD dwIndex;
AtariError iRet;
char szEntry[40];
struct _stat buf;

     /*
      * check file size.
      * Only xfd file of 92160 bytes are supported.
      */
     if (_stat(szFile, &buf))
          {
          MessageBox(hDlg, "Atari error:\nFile not found !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
          return FALSE;
          }
     if ((buf.st_size != 92160L) && (buf.st_size != 92176L))
          {
          MessageBox(hDlg, "Atari error:\nNot an XFD/ATR file or density not supported (wrong file size) !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
          return FALSE;
          }

     /*
      * reset the atari file name list
      */
     SendDlgItemMessage(hDlg, IDC_LISTEATARI, LB_RESETCONTENT, 0, 0L);

     /*
      * get all the file names one by one.
      */
     wTotal = 0;
     iRet = AtariFindFirst(szFile, &Info);
     ShowAtariError(hDlg, iRet);
     while (iRet == ATARI_ERR_OK)
          {

          /*
           * add file size to total size
           */
          wTotal += Info.wSize;

          /*
           * build list box entry with the file name and the length.
           */
          strcpy(szEntry, Info.szName);

          /*
           * add space at the end of the name to make the TAB work.
           */
          for (wLng = 13 - strlen(szEntry); wLng > 1; wLng--)
               strcat(szEntry, " ");

          /*
           * add the number of sector of the file in the string.
           */
          wsprintf(&szEntry[strlen(szEntry)], "\t%d", Info.wSize);

          /*
           * add file name to the list and keep the directory index for
           * a selection.
           */
          dwIndex = SendDlgItemMessage(hDlg, IDC_LISTEATARI, LB_ADDSTRING, 0, (LPARAM) (LPSTR) szEntry);
          SendDlgItemMessage(hDlg, IDC_LISTEATARI, LB_SETITEMDATA, (WORD) dwIndex, (LPARAM) Info.lIndex);

          /*
           * get the next file name.
           */
          iRet = AtariFindNext(szFile, &Info);
          ShowAtariError(hDlg, iRet);
          }

     /*
      * show total file size.
      */
     if (iRet == ATARI_ERR_OK || iRet == ATARI_ERR_NO_ENTRY_FOUND)
          {
          SetDlgItemInt(hDlg, wTotalID, wTotal, FALSE);
          return TRUE;
          }
     else {
          SetDlgItemText(hDlg, wTotalID, "");
          return FALSE;
          }
}

static BOOL SaveAtariToPC(HWND hDlg, char *szFile, FILE *fdPC, AtariFile *Info, BOOL bConversion)
{
unsigned wNbSector;
unsigned wIndex;
AtariError iRet;

     /*
      * boucle de lecture de tous les secteurs du fichier.
      */
     wNbSector = Info->wSize;
     if ((iRet = AtariReadFirstSector(szFile, Info)) != ATARI_ERR_END_OF_FILE)
          ShowAtariError(hDlg, iRet);
     while ((iRet == ATARI_ERR_OK) && (Info->wSectorLng > 0))
          {
          wNbSector--;
          if (bConversion == FALSE)
               {
               if (fwrite(Info->szSector, Info->wSectorLng, 1, fdPC) != 1)
                    {
                    MessageBox(hDlg, "Can not write to PC file !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
                    return FALSE;
                    }
               }
          else {
               for (wIndex = 0; wIndex < Info->wSectorLng; wIndex++)
                    {
                    if ((unsigned char) Info->szSector[wIndex] == (unsigned char) 0x9B)
                         {
                         if (fwrite("\r\n", 2, 1, fdPC) != 1)
                              {
                              MessageBox(hDlg, "Can not write to PC file !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
                              return FALSE;
                              }
                         }
                    else if (Info->szSector[wIndex] == 0x7F)
                         {
                         if (fwrite("\t", 1, 1, fdPC) != 1)
                              {
                              MessageBox(hDlg, "Can not write to PC file !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
                              return FALSE;
                              }
                         }
                    else {
                         if (fwrite(&(Info->szSector[wIndex]), 1, 1, fdPC) != 1)
                              {
                              MessageBox(hDlg, "Can not write to PC file !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
                              return FALSE;
                              }
                         }
                    }
               }
          if ((iRet = AtariReadNextSector(szFile, Info)) != ATARI_ERR_END_OF_FILE)
               ShowAtariError(hDlg, iRet);
          }

     if ((iRet == ATARI_ERR_END_OF_FILE) && (wNbSector))
          {
          ShowAtariError(hDlg, ATARI_ERR_FILE_LENGTH);
          return FALSE;
          }
     return TRUE;
}

static BOOL ExportAtariFile(HWND hDlg, char *szFile, char *szDirPC, long lDirIndex, BOOL bConversion)
{
AtariFile Info;
AtariError iRet;
BOOL bRet;
char szPCFile[_MAX_PATH];
FILE *fdPC;

     /*
      * get file information from directory entry.
      */
     if ((iRet = AtariGetFileFromIndex(szFile, &Info, lDirIndex)) != ATARI_ERR_OK)
          {
          ShowAtariError(hDlg, iRet);
          return FALSE;
          }
     
     /*
      * build the full path name for the PC file.
      */
     memset(szPCFile, 0, sizeof(szPCFile));
     strcpy(szPCFile, szDirPC);
     if (szPCFile[strlen(szPCFile) - 1] != '\\')
          strcat(szPCFile, "\\");
     strcat(szPCFile, Info.szName);

     /*
      * the PC file is opened.
      */
     if (fdPC = fopen(szPCFile, "rb"))
          {
          fclose(fdPC);

          /*
           * ask user to overwrite PC file.
           */
          wsprintf(szErr, "File %s already exists !\nOverwrite it ?", szPCFile);
          if (MessageBox(hDlg, szErr, TITRE_TRANSFERT, MB_YESNO | MB_ICONQUESTION) == IDNO)
               return TRUE;
          }
     if ((fdPC = fopen(szPCFile, "wb")) == NULL)
          {
          wsprintf(szErr, "File %s can not be created !", szPCFile);
          MessageBox(hDlg, szErr, TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
          return FALSE;
          }

     /*
      * data transfert from Atari to PC.
      */
     bRet = SaveAtariToPC(hDlg, szFile, fdPC, &Info, bConversion);
     fclose(fdPC);
     return bRet;
}

static BOOL SavePCToAtari(HWND hDlg, char *szFile, FILE *fdPC, AtariFile *Info, BOOL bConversion)
{
AtariError iRet;
unsigned char c;

     if (bConversion == FALSE)
          {
          while (Info->wSectorLng = fread(Info->szSector, 1, 125, fdPC))
               {
               if ((iRet = AtariWriteSector(szFile, Info)) != ATARI_ERR_OK)
                    {
                    ShowAtariError(hDlg, iRet);
                    return FALSE;
                    }
               }
          }
     else {
          Info->wSectorLng = 0;
          while (fread(&c, 1, 1, fdPC))
               {
               if (c == '\t')
                    Info->szSector[(Info->wSectorLng)++] = 0x7F;
               else if (c == '\n')
                    Info->szSector[(Info->wSectorLng)++] = 0x9B;
               else if (c != '\r')
                    Info->szSector[(Info->wSectorLng)++] = c;
               if (Info->wSectorLng == 125)
                    {
                    if ((iRet = AtariWriteSector(szFile, Info)) != ATARI_ERR_OK)
                         {
                         ShowAtariError(hDlg, iRet);
                         return FALSE;
                         }
                    Info->wSectorLng = 0;
                    }
               }
          if (Info->wSectorLng)
               if ((iRet = AtariWriteSector(szFile, Info)) != ATARI_ERR_OK)
                    {
                    ShowAtariError(hDlg, iRet);
                    return FALSE;
                    }
          }
     if (! feof(fdPC))
          {
          MessageBox(hDlg, "Can not read PC file !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
          return FALSE;
          }
     return TRUE;
}

static BOOL ImportAtariFile(HWND hDlg, char *szFile, char *szDirPC, char *szFilePC, BOOL bConversion)
{
AtariFile Info;
AtariError iRet;
BOOL bRet;
char szPCFile[_MAX_PATH];
FILE *fdPC;
     
     /*
      * build the full path name for the PC file.
      */
     memset(szPCFile, 0, sizeof(szPCFile));
     strcpy(szPCFile, szDirPC);
     if (szPCFile[strlen(szPCFile) - 1] != '\\')
          strcat(szPCFile, "\\");
     strcat(szPCFile, szFilePC);

     /*
      * the PC file is opened.
      */
     if ((fdPC = fopen(szPCFile, "rb")) == NULL)
          {
          wsprintf(szErr, "File %s can not be created !", szPCFile);
          MessageBox(hDlg, szErr, TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
          return FALSE;
          }

     /*
      * check that the file does not already exist on Atari disk.
      */
     switch (iRet = AtariCheckFile(szFile, &Info, szFilePC))
          {
          case ATARI_ERR_OK:

               /*
                * ask user to overwrite Atari file.
                */
               wsprintf(szErr, "File %s already exists !", szFilePC);
               MessageBox(hDlg, szErr, TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
               fclose(fdPC);
               return TRUE;

          case ATARI_ERR_NO_ENTRY_FOUND:
               break;

          default:
               ShowAtariError(hDlg, iRet);
               fclose(fdPC);
               return FALSE;
          }

     /*
      * create Atari file
      */
     if (iRet = AtariCreateFile(szFile, &Info, szFilePC))
          {
          ShowAtariError(hDlg, iRet);
          fclose(fdPC);
          return FALSE;
          }

     /*
      * data transfert from PC to Atari.
      */
     bRet = SavePCToAtari(hDlg, szFile, fdPC, &Info, bConversion);
     fclose(fdPC);
     return bRet;
}

static void TransferChangeDrive(HWND hDlg, LPSTR szFilter)
{
DWORD dwIndex;

     SendDlgItemMessage(hDlg, IDC_REPERTOIREPC, WM_SETREDRAW, FALSE, 0);
     SendDlgItemMessage(hDlg, IDC_REPERTOIREPC, LB_RESETCONTENT, 0, 0);
     SendDlgItemMessage(hDlg, IDC_REPERTOIREPC, LB_DIR, DDL_DIRECTORY | DDL_EXCLUSIVE, (LPARAM) szFilter);
     SendDlgItemMessage(hDlg, IDC_REPERTOIREPC, WM_SETREDRAW, TRUE, 0);
     SendDlgItemMessage(hDlg, IDC_FICHIERSPC, WM_SETREDRAW, FALSE, 0);
     SendDlgItemMessage(hDlg, IDC_FICHIERSPC, LB_RESETCONTENT, 0, 0);
     SendDlgItemMessage(hDlg, IDC_FICHIERSPC, LB_DIR, DDL_READWRITE | DDL_READONLY | DDL_ARCHIVE, (LPARAM) szFilter);
     SendDlgItemMessage(hDlg, IDC_FICHIERSPC, WM_SETREDRAW, TRUE, 0);
     dwIndex = SendDlgItemMessage(hDlg, IDC_LECTEURPC, CB_GETCURSEL, 0, 0L);
     SendDlgItemMessage(hDlg, IDC_LECTEURPC, CB_GETLBTEXT, (WPARAM) dwIndex, (LPARAM) (LPCSTR) szTransferDirPC);
     _getdcwd(szTransferDirPC[2] - 'a' + 1, szTransferPath, sizeof(szTransferPath) - 1);
     strlwr(szTransferPath);
     SetDlgItemText(hDlg, IDC_CHEMINPC, szTransferPath);
     InvalidateRect(GetDlgItem(hDlg, IDC_REPERTOIREPC), NULL, TRUE);
     InvalidateRect(GetDlgItem(hDlg, IDC_FICHIERSPC), NULL, TRUE);
}

/*
** setup all dialog box fields
*/
static void TransferInit(HWND hDlg)
{
     SetDlgItemText(hDlg, IDC_DISQUEATARI, "");
     SetDlgItemText(hDlg, IDC_TAILLE, "");
     EnableWindow(GetDlgItem(hDlg, IDC_PARCOURIR), TRUE);
     EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
     EnableWindow(GetDlgItem(hDlg, IDC_IMPORTER), FALSE);
     EnableWindow(GetDlgItem(hDlg, IDC_EXPORTER), FALSE);
     CheckDlgButton(hDlg, IDC_CONVERTIR, FALSE);
     SendDlgItemMessage(hDlg, IDC_LISTEATARI, LB_RESETCONTENT, 0, 0L);
     SendDlgItemMessage(hDlg, IDC_LECTEURPC, CB_RESETCONTENT, 0, 0L);
     SendDlgItemMessage(hDlg, IDC_REPERTOIREPC, LB_RESETCONTENT, 0, 0L);
     SendDlgItemMessage(hDlg, IDC_FICHIERSPC, LB_RESETCONTENT, 0, 0L);
     PostMessage(hDlg, WM_USER + 1234, 0, 0L);
     PostMessage(hDlg, WM_COMMAND, IDC_PARCOURIR, 0L);

     /*
     ** fill PC drive, directory and file list boxes.
     */
     SendDlgItemMessage(hDlg, IDC_LECTEURPC, CB_DIR, DDL_DRIVES | DDL_EXCLUSIVE, (LPARAM) (LPSTR) "*.*");
     wsprintf(szTransferDirPC, "[-%c-]", _getdrive() + 'a' - 1);
     SendDlgItemMessage(hDlg, IDC_LECTEURPC, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) (LPCSTR) szTransferDirPC);
     TransferChangeDrive(hDlg, "*.*");
     bTransferDiskLoaded = FALSE;
     bTransferAtariSelected = FALSE;
     bTransferPCSelected = FALSE;
     memset(szTransferFile, 0, sizeof(szTransferFile));
}

BOOL __export CALLBACK TransferProc(HWND hDlg, unsigned message, WPARAM wParam, LPARAM lParam)
{
BOOL bNotEmpty;
BOOL bConversion;
int nSelCount;
int nItem;
long lDirIndex;
DWORD dwIndex;

     switch (message)
          {
          case WM_INITDIALOG:
               TransferInit(hDlg);
               return TRUE;

          case WM_COMMAND:
               switch (wParam)
                    {
                    case IDC_PARCOURIR:

                         /*
                          * ouvre la boite standard de selection de fichier
                          * pour que l'utilisateur choisisse un disque Atari.
                          */
                         if (GetFileName(hDlg, szTransferFile,
                                         OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST,
                                         IDS_OPEN_DISK_IMAGE,
                                         "ATR files\0*.ATR\0XFD files\0*.XFD\0All files\0*.*\0\0"))
                              {
                              strlwr(szTransferFile);
                              SetDlgItemText(hDlg, IDC_DISQUEATARI, szTransferFile);
                              PostMessage(hDlg, WM_COMMAND, IDOK, 0L);
                              }
                         return TRUE;

                    case IDC_DISQUEATARI:

                         /*
                          * sur un changement du nom du fichier disque Atari,
                          * on verifie qu'il y a au moins un caractere.
                          * Dans ce cas, l'utilisateur peut cliquer sur le
                          * bouton Lire.
                          */
                         if (HIWORD(lParam) == EN_CHANGE)
                              {
                              bNotEmpty = (BOOL) SendDlgItemMessage(hDlg, IDC_DISQUEATARI, WM_GETTEXTLENGTH, 0, 0L);
                              EnableWindow(GetDlgItem(hDlg, IDOK), bNotEmpty);
                              bTransferDiskLoaded = FALSE;
                              bTransferAtariSelected = FALSE;
                              SendDlgItemMessage(hDlg, IDC_LISTEATARI, LB_RESETCONTENT, 0, 0L);
                              SetDlgItemText(hDlg, IDC_TAILLE, "");
                              EnableWindow(GetDlgItem(hDlg, IDC_EXPORTER), bTransferAtariSelected);
                              EnableWindow(GetDlgItem(hDlg, IDC_IMPORTER), bTransferDiskLoaded && bTransferPCSelected);
                              }
                         return TRUE;

                    case IDC_LISTEATARI:

                         /*
                          * selon la selection, les boutons concernant celle-ci
                          * sont grises ou autorises.
                          */
                         if (HIWORD(lParam) == LBN_SELCHANGE)
                              {
                              bTransferAtariSelected = FALSE;
                              if (bTransferDiskLoaded)
                                   {
                                   nSelCount = (int) SendDlgItemMessage(hDlg, IDC_LISTEATARI, LB_GETSELCOUNT, 0, 0L);
                                   if (nSelCount > 0)
                                        bTransferAtariSelected = TRUE;
                                   }
                              EnableWindow(GetDlgItem(hDlg, IDC_EXPORTER), bTransferAtariSelected);
                              }
                         return TRUE;

                    case IDC_LECTEURPC:
                         if (HIWORD(lParam) == CBN_SELCHANGE)
                              {
                              if ((dwIndex = SendDlgItemMessage(hDlg, IDC_LECTEURPC, CB_GETCURSEL, 0, 0L)) != CB_ERR)
                                   {
                                   SendDlgItemMessage(hDlg, IDC_LECTEURPC, CB_GETLBTEXT, (WPARAM) dwIndex, (LPARAM) (LPCSTR) szTransferDirPC);
                                   if (_chdrive(szTransferDirPC[2] - 'a' + 1))
                                        MessageBox(hDlg, "Error while changing of drive !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
                                   else {
                                        SetDlgItemText(hDlg, IDC_LECTEURPC, szTransferDirPC);
                                        TransferChangeDrive(hDlg, "*.*");
                                        PostMessage(hDlg, WM_COMMAND, IDC_FICHIERSPC, MAKELONG(0, LBN_SELCHANGE));
                                        }
                                   }
                              }
                         return TRUE;

                    case IDC_REPERTOIREPC:
                         if (HIWORD(lParam) == LBN_DBLCLK)
                              {
                              if ((dwIndex = SendDlgItemMessage(hDlg, IDC_REPERTOIREPC, LB_GETCURSEL, 0, 0L)) != LB_ERR)
                                   {
                                   SendDlgItemMessage(hDlg, IDC_REPERTOIREPC, LB_GETTEXT, (WPARAM) dwIndex, (LPARAM) (LPCSTR) szTransferDirPC);
                                   if (strlen(szTransferDirPC))
                                        szTransferDirPC[strlen(szTransferDirPC) - 1] = 0;
                                   GetDlgItemText(hDlg, IDC_CHEMINPC, szTransferPath, sizeof(szTransferPath) - 1);
                                   BuildPath(szErr, szTransferPath, szTransferDirPC + 1);
                                   if (_chdir(szErr))
                                        MessageBox(hDlg, "Error while changing of directory !", TITRE_TRANSFERT, MB_OK | MB_ICONEXCLAMATION);
                                   else {
                                        wsprintf(szErr, "%2.2s*.*", szTransferPath);
                                        TransferChangeDrive(hDlg, szErr);
                                        PostMessage(hDlg, WM_COMMAND, IDC_FICHIERSPC, MAKELONG(0, LBN_SELCHANGE));
                                        }
                                   }
                              }
                         return TRUE;

                    case IDC_FICHIERSPC:

                         /*
                          * selon la selection, les boutons concernant celle-ci
                          * sont grises ou autorises.
                          */
                         if (HIWORD(lParam) == LBN_SELCHANGE)
                              {
                              nSelCount = (int) SendDlgItemMessage(hDlg, IDC_FICHIERSPC, LB_GETSELCOUNT, 0, 0L);
                              if (nSelCount > 0)
                                   bTransferPCSelected = TRUE;
                              else bTransferPCSelected = FALSE;
                              EnableWindow(GetDlgItem(hDlg, IDC_IMPORTER), bTransferDiskLoaded && bTransferPCSelected);
                              }
                         return TRUE;

                    case IDOK:

                         /*
                          * sur l'appui du bouton Lire, le champ Disque Atari
                          * est lu et le repertoire du fichier disque Atari
                          * est affiche dans la liste.
                          */
                         bNotEmpty = (BOOL) SendDlgItemMessage(hDlg, IDC_DISQUEATARI, WM_GETTEXTLENGTH, 0, 0L);
                         if (! bNotEmpty)
                              return TRUE;
                         GetDlgItemText(hDlg, IDC_DISQUEATARI, szTransferFile, sizeof(szTransferFile));
                         if (ReadAtariDirectory(hDlg, szTransferFile, IDC_LISTEATARI, IDC_TAILLE))
                              bTransferDiskLoaded = TRUE;
                         EnableWindow(GetDlgItem(hDlg, IDC_IMPORTER), bTransferDiskLoaded && bTransferPCSelected);
                         PostMessage(hDlg, WM_COMMAND, IDC_LISTEATARI, MAKELONG(0, LBN_SELCHANGE));
                         return TRUE;

                    case IDC_EXPORTER:

                         /*
                          * les fichiers Atari selectionnes sont stockes sur
                          * le disque du PC (et convertis si necessaire).
                          */
                         if (bTransferDiskLoaded)
                              {
                              GetDlgItemText(hDlg, IDC_DISQUEATARI, szTransferFile, sizeof(szTransferFile));
                              GetDlgItemText(hDlg, IDC_CHEMINPC, szTransferDirPC, sizeof(szTransferDirPC));
                              bConversion = IsDlgButtonChecked(hDlg, IDC_CONVERTIR);
                              nSelCount = (int) SendDlgItemMessage(hDlg, IDC_LISTEATARI, LB_GETCOUNT, 0, 0L);
                              for (nItem = 0; nItem < nSelCount; nItem++)
                                   if (SendDlgItemMessage(hDlg, IDC_LISTEATARI, LB_GETSEL, (WORD) nItem, 0L))
                                        {
                                        lDirIndex = SendDlgItemMessage(hDlg, IDC_LISTEATARI, LB_GETITEMDATA, (WORD) nItem, 0L);
                                        if (ExportAtariFile(hDlg, szTransferFile, szTransferDirPC, lDirIndex, bConversion) == FALSE)
                                             {
                                             wsprintf(szErr, "%s%s*.*", szTransferDirPC, (szTransferDirPC[strlen(szTransferDirPC) - 1] == '\\' ? "" : "\\"));
                                             DlgDirList(hDlg, szErr, IDC_FICHIERSPC, 0, DDL_READWRITE | DDL_READONLY | DDL_ARCHIVE);
                                             break;
                                             }
                                        SendDlgItemMessage(hDlg, IDC_LISTEATARI, LB_SETSEL, FALSE, MAKELONG(nItem, 0));
                                        wsprintf(szErr, "%s%s*.*", szTransferDirPC, (szTransferDirPC[strlen(szTransferDirPC) - 1] == '\\' ? "" : "\\"));
                                        DlgDirList(hDlg, szErr, IDC_FICHIERSPC, 0, DDL_READWRITE | DDL_READONLY | DDL_ARCHIVE);
                                        }
                              PostMessage(hDlg, WM_COMMAND, IDC_LISTEATARI, MAKELONG(0, LBN_SELCHANGE));
                              }
                         return TRUE;

                    case IDC_IMPORTER:

                         /*
                          * les fichiers PC selectionnes sont stockes sur
                          * le disque Atari (et convertis si necessaire).
                          */
                         if (bTransferDiskLoaded)
                              {
                              GetDlgItemText(hDlg, IDC_DISQUEATARI, szTransferFile, sizeof(szTransferFile));
                              GetDlgItemText(hDlg, IDC_CHEMINPC, szTransferDirPC, sizeof(szTransferDirPC));
                              if (szTransferDirPC[strlen(szTransferDirPC) - 1] != '\\')
                                   strcat(szTransferDirPC, "\\");
                              bConversion = IsDlgButtonChecked(hDlg, IDC_CONVERTIR);
                              nSelCount = (int) SendDlgItemMessage(hDlg, IDC_FICHIERSPC, LB_GETCOUNT, 0, 0L);
                              for (nItem = 0; nItem < nSelCount; nItem++)
                                   if (SendDlgItemMessage(hDlg, IDC_FICHIERSPC, LB_GETSEL, (WORD) nItem, 0L))
                                        {
                                        SendDlgItemMessage(hDlg, IDC_FICHIERSPC, LB_GETTEXT, (WPARAM) nItem, (LPARAM) (LPSTR) szTransferFilePC);
                                        if (ImportAtariFile(hDlg, szTransferFile, szTransferDirPC, szTransferFilePC, bConversion) == FALSE)
                                             {
                                             PostMessage(hDlg, WM_COMMAND, IDOK, 0L);
                                             break;
                                             }
                                        SendDlgItemMessage(hDlg, IDC_FICHIERSPC, LB_SETSEL, FALSE, MAKELONG(nItem, 0));
                                        PostMessage(hDlg, WM_COMMAND, IDOK, 0L);
                                        }
                              PostMessage(hDlg, WM_COMMAND, IDC_FICHIERSPC, MAKELONG(0, LBN_SELCHANGE));
                              }
                         return TRUE;

                    case IDCANCEL:
                         EndDialog(hDlg, FALSE);
                         return TRUE;
                    }
               break;

          case WM_CTLCOLOR:

               /*
               ** change background color to gray.
               */
               if (HIWORD(lParam) == CTLCOLOR_STATIC || HIWORD(lParam) == CTLCOLOR_BTN || HIWORD(lParam) == CTLCOLOR_DLG)
                    {
                    SetBkColor((HDC) wParam, RGB(192, 192, 192));
                    return (BOOL) GetStockObject(LTGRAY_BRUSH);
                    }
               return FALSE;
          }
     return FALSE;
}

long TransferFile(HWND hWnd)
{
     DialogBox(hInst, "TRANSFERBOX", hWnd, TransferProc);
     return NULL;
}
